using System;
using UnityEngine;




namespace UFrame
{
    public enum EEffectPlayType
    {
        Normal,
        Bind,
        BindPosition,
        Track,
        Motion,
    }


    public class EffectUnitPOD
    {

    }



    public class EffectUnitMB : MonoBehaviour
    {
        EffectPlayMB controller;

        public EffectUnitPOD config = null;

        public float lifeTime = float.Epsilon;

        protected float curTime = float.Epsilon;

        protected Transform start;
        protected Transform end;
        protected Vector3 endPos;

        protected Transform bindBone = null;

        protected Vector3 offset = Vector3.zero;

        protected Quaternion rotation = Quaternion.identity;

        protected Quaternion casterRotation = Quaternion.identity;

        protected float duration;

        protected Action action;

        protected bool isMove = false;

        public EEffectPlayType playType = EEffectPlayType.Normal;

        // 轨迹特效开始点
        private Vector3 trackStartPos;

        // 运动速度变化
        private AnimationCurve curveSpeed;
        private float motionOffsetX;
        private float motionOffsetY;
        private AnimationCurve curveMotionOffsetX;
        private AnimationCurve curveMotionOffsetY;

        private Vector3 lastPosition;

        public void Init(string name)
        {
            curTime = float.Epsilon;
        }

        /*
        public virtual void Init( EffectDef _config, CharacterUnitBase _firer, CharacterUnitBase _target, Vector3 _pos )
        {            
            m_config = _config;            
            m_cur_time = float.Epsilon;
            BindPosition( _config, _firer, _target, _pos );
            if(m_controller != null)
                m_controller.RePlay();
        }
*/

        public void SetPosition(Vector3 pos)
        {
            transform.position = pos;
            trackStartPos = pos;
        }

        public void BindBone(Transform t, float offer = 0)
        {
            transform.SetParent(t);
            transform.localPosition = Vector3.zero + new Vector3(0, offer, 0);
        }

        public void SetOffer(Vector3 offer)
        {
            transform.localPosition = offer;
        }

        public void LeaveBone()
        {
            transform.SetParent(null);
        }

        public void SetLifeTime(float life)
        {
            lifeTime = life;
        }

        public void SetBindPosition(Transform bone, Vector3 offer, Quaternion rotation, Quaternion casterRotation)
        {
            bindBone = bone;
            offset = offer;
            this.rotation = rotation;
            this.casterRotation = casterRotation;
            transform.localRotation = casterRotation * rotation;
            playType = EEffectPlayType.BindPosition;
        }

        /// <summary>
        /// 跟踪型，start为null则不锁定玩家
        /// </summary>
        /// <param name="target"></param>
        /// <param name="offer"></param>
        /// <param name="duration"></param>
        /// <param name="rotation"></param>
        /// <param name="curve"></param>
        /// <param name="action"></param>
        /// <param name="start"></param>
        public void SetMove(Transform target, Vector3 offer, float duration, Quaternion rotation, AnimationCurve curve,
            Action action, Transform start = null)
        {
            this.duration = duration;
            end = target;
            this.start = start;
            this.action = action;
            offset = offer;
            casterRotation = rotation;
            curveSpeed = curve;
            trackStartPos = transform.position;
            lastPosition = trackStartPos;
            playType = EEffectPlayType.Track;
        }

        // 运动型
        public void SetMove(Vector3 target, Vector3 offer, float duration, Quaternion rotation, AnimationCurve curve,
            Action action, Transform start = null)
        {
            this.duration = duration;
            endPos = target;
            this.start = start;
            this.action = action;
            offset = offer;
            casterRotation = rotation;
            curveSpeed = curve;
            trackStartPos = transform.position;
            lastPosition = trackStartPos;
            playType = EEffectPlayType.Motion;
        }

        public void SetMoveOffset(float x, float y, AnimationCurve xCurve, AnimationCurve yCurve)
        {
            motionOffsetX = x;
            motionOffsetY = y;
            curveMotionOffsetX = xCurve;
            curveMotionOffsetY = yCurve;
        }


        public virtual void UpdateEffectSus()
        {
            switch (playType)
            {
                case EEffectPlayType.Track:
                    {
                        if (end == null)
                        {
                            //PoolUnInitObject();
                            //放入对象池
                            return;
                        }

                        float t = curTime / Mathf.Max(0.001f, duration);
                        float offsetT = curveSpeed.Evaluate(t);
                        Vector3 startPos = (start != null) ? start.position : trackStartPos;
                        Vector3 targetPos = Vector3.Lerp(startPos, end.position + Vector3.up, curveSpeed.Evaluate(t));
                        Vector3 offset = Vector3.zero;
                        if (motionOffsetX != 0)
                        {
                            offset += Vector3.right * curveMotionOffsetX.Evaluate(offsetT) * motionOffsetX;
                        }

                        if (motionOffsetY != 0)
                        {
                            offset += Vector3.up * curveMotionOffsetY.Evaluate(offsetT) * motionOffsetY;
                        }

                        // 偏移后追踪                                                
                        transform.position = targetPos + casterRotation * offset;

                        if (!lastPosition.Equals(transform.position))
                        {
                            transform.forward = (transform.position - lastPosition).normalized;
                            lastPosition = transform.position;
                        }

                        if (curTime >= duration)
                        {
                            if (action != null)
                            {
                                action();
                            }

                            //PoolUnInitObject();            //存储对象池
                            return;
                        }

                        curTime += Time.deltaTime;
                        break;
                    }
                case EEffectPlayType.Motion:
                    {
                        float t = curTime / Mathf.Max(0.001f, duration);
                        Vector3 startPos = (start != null) ? start.position : trackStartPos;
                        Vector3 targetPos = Vector3.Lerp(startPos, endPos + Vector3.up, curveSpeed.Evaluate(t));
                        Vector3 offset = Vector3.zero;

                        if (motionOffsetX != 0)
                        {
                            offset += Vector3.right * curveMotionOffsetX.Evaluate(t) * motionOffsetX;
                        }

                        if (motionOffsetY != 0)
                        {
                            offset += Vector3.up * curveMotionOffsetY.Evaluate(t) * motionOffsetY;
                        }

                        // 偏移后追踪                                                
                        transform.position = targetPos + casterRotation * offset;

                        if (!lastPosition.Equals(transform.position))
                        {
                            transform.forward = (transform.position - lastPosition).normalized;
                            lastPosition = transform.position;
                        }

                        if (curTime >= duration)
                        {
                            if (action != null)
                            {
                                action();
                            }

                            //PoolUnInitObject();
                            //TODO 存入对象池

                            return;
                        }

                        curTime += Time.deltaTime;
                        break;
                    }
                default:


                    if (playType == EEffectPlayType.BindPosition && bindBone != null)
                    {
                        transform.position = bindBone.position + casterRotation * offset;
                    }

                    if (lifeTime <= float.Epsilon)
                    {
                        return;
                    }

                    if (curTime >= lifeTime)
                    {
                        //PoolUnInitObject();
                        //TODO 存入对象池
                        return;
                    }

                    curTime += Time.deltaTime;

                    break;
            }
        }

        private void OnEnable()
        {
            curTime = 0f;
            end = null;
        }

        private void Update()
        {
            UpdateEffectSus();
        }

        public void BindPosition(MeshControl meshControl)
        {
            Transform tf = meshControl.GetBoneByName("");
            if (tf != null)
            {
                transform.SetParent(null, false);
                transform.position = tf.position;
                transform.localScale = Vector3.one;
                transform.rotation = tf.rotation;
            }
        }
    }
}